#ifndef INFINITY_CELL_CLUSTER_MANAGER_H
#	define INFINITY_CELL_CLUSTER_MANAGER_H

#include "cellcluster.h"
#include "cellclustercube.h"
#include "cellclustermarchingcube.h"

#include "worldgridmanager.h"
#include "base/singleton.h"

#include "planet.h"
#include "planeteventlistener.h"
#include "planeteventarg.h"

#include "graphics/node.h"

namespace infinity {
	namespace render {

//! @todo this should be integrated to the world service
class CellClusterManager
:	public dw::base::Singleton< CellClusterManager >
,	public Planet::EventListener
{
public : //! @name Constants
	//! @{
	static const dw::uint32 ClusterSize = 16;
	static const dw::uint32 MaxGenerationPerFrame = 4;
	static const dw::int32 VisionRadius = 32 / 16; // we want to see 96 cells away
	//! @}

public : //! @name Commands
	//! @{
	void update(dw::float32 deltaT);
	void render(dw::graphics::Renderer& renderer);
	//!@}

public : //! @name Setup
	//! @{
	void setCameraNode(const dw::graphics::Node* cameraNode);
	//! @}

public : //! @name Planet::EventListener Callbacks
	//! @{
	void onCellChanged(Planet& sender, Planet::CellEventArg& eventArg);
	//! @}

protected : //! @name Construction & Destruction
	//! @{
	friend dw::base::Singleton< CellClusterManager >;

	CellClusterManager();
	~CellClusterManager();
	//! @}

private : //! @name Types definitions
	//! @{
	struct CellClusterHolder
	{
		Vector3i clusterPos;
		CellCluster* cluster;
		dw::float32 priority;
		bool isGenerated;
	};
	typedef std::vector< CellClusterHolder > ClustersCollection;
	//! @}

private : //! @name Helpers
	//! @{
	static bool clusterPriorityComp(const CellClusterHolder& lhs, const CellClusterHolder& rhs);
	CellClusterHolder* findClusterHolder(const Vector3i& clusterID, dw::float32 priority);
	CellClusterHolder* findClusterHolder(const Vector3i& clusterID); //!< strict
	//! @}

private : //! @name Data
	//! @{
	const dw::graphics::Node* m_cameraNode;
	ClustersCollection m_clusters;
};

	} // namespace render
} // namespace infinity

#endif // !INFINITY_CELL_CLUSTER_MANAGER_H
